import { TSUN_BLE_CRYPTO_KEYS } from '@/config/config';
import AppEnvironments from '@/services/AppEnvironment';
import { Buffer } from 'buffer';
import QuickCrypto from 'react-native-quick-crypto';

export default {
  isEmpty(str: string | undefined | null): boolean {
    return str === undefined || str === null || !str;
  },

  isNotEmpty(str: string | undefined | null): boolean {
    return str !== undefined && str !== null && str.length > 0;
  },

  toImageUri(str: string | null | undefined): string {
    if (!str) {
      return '';
    }
    if (str.startsWith('http')) {
      return str;
    } else if (str.startsWith('file://')) {
      return str;
    }
    return (
      AppEnvironments.current.ossURL + str
    );
  },
  isValidEmail(email: string): boolean {
    const emailRegex = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i;
    return emailRegex.test(email);
  },
  isValidPhoneNumber(phoneNumber: string): boolean {
    const phoneRegex = /^1[3-9]\d{9}$/;
    return phoneRegex.test(phoneNumber);
  },
  /// 加密逻辑，得到IV，密文，tag的字节数组，按照顺序拼接在一起
  encryptContentForTSUNBle(content: string, keyIndex: number = 0): number[] {
    if (keyIndex == 0 || keyIndex > TSUN_BLE_CRYPTO_KEYS.length) {
      return Buffer.from(content, 'utf-8').toJSON().data;
    }
    const key = TSUN_BLE_CRYPTO_KEYS[keyIndex - 1];
    const iv = QuickCrypto.randomBytes(12).toString('hex');
    const encryptedContent = this.encryptAES128GCM(content, key, iv);
    return [
      ...encryptedContent.iv,
      ...encryptedContent.bytes,
      ...encryptedContent.tag,
    ];
  },
  /// 解密逻辑，如果明文，直接返回；密文，则转成hex字符串，截取后再解密
  decryptContentForTSUNBle(byteArray: number[], keyIndex: number = 0): string {
    if (keyIndex == 0 || keyIndex > TSUN_BLE_CRYPTO_KEYS.length) {
      return Buffer.from(byteArray).toString('utf-8');
    }
    try {
      const content = Buffer.from(byteArray).toString('hex');
      const ivHex = content.substring(0, 24); // 前24字符
      const ciphertextHex = content.substring(24, content.length - 32); // 中间部分
      const tagHex = content.substring(content.length - 32); // 最后32字符
      // const [iv, rawContent, tag] = content.split(',');
      const key = TSUN_BLE_CRYPTO_KEYS[keyIndex - 1];
      const decryptedContent = this.decryptAES128GCM(
        ciphertextHex,
        key,
        ivHex,
        tagHex
      );
      return decryptedContent;
    } catch (e) {
      return '';
    }
  },

  /**
   * 蓝牙加密
   * @param plainText 需要加密的源文本
   * @param keyHex 加密的key，16位hex
   * @param ivHex 加密的iv，12位hex
   * @returns 加密后的文本，bytes，tag，iv
   */
  encryptAES128GCM(
    plainText: string,
    keyHex: string,
    ivHex: string
  ): {
    text: string;
    bytes: number[];
    tag: number[];
    iv: number[];
  } {
    const key = Buffer.from(keyHex, 'hex');
    const iv = Buffer.from(ivHex, 'hex');

    const cipher = QuickCrypto.createCipheriv('aes-128-gcm', key, iv);

    const encrypted = Buffer.concat([
      cipher.update(plainText, 'utf8'),
      cipher.final(),
    ]);
    const tag = cipher.getAuthTag();
    // const encryptedInfo = {
    //   text: encrypted.toString('hex'),
    //   bytes: encrypted.toJSON().data,
    //   tag: tag.toString('hex'),
    //   iv: iv.toString('hex'),
    // };

    const encryptedInfo = {
      text: encrypted.toString('hex'),
      bytes: encrypted.toJSON().data,
      tag: tag.toJSON().data,
      iv: iv.toJSON().data,
    };

    return encryptedInfo;
  },

  /**
   * 蓝牙解密
   * @param cipherText 需要解密的文本
   * @param keyHex 解密的key，16位hex
   * @param ivHex 解密的iv，12位hex
   * @param tagHex 解密的tag，加密的时候获得
   * @returns 解密后的文本
   */
  decryptAES128GCM(
    encryptedTextHex: string,
    keyHex: string,
    ivHex: string,
    tagHex: string
  ): string {
    const key = Buffer.from(keyHex, 'hex');
    const iv = Buffer.from(ivHex, 'hex');
    const tag = Buffer.from(tagHex, 'hex');
    const decipher = QuickCrypto.createDecipheriv('aes-128-gcm', key, iv, {
      authTagLength: 16,
    });
    decipher.setAuthTag(tag);
    try {
      const decrypted = Buffer.concat([
        decipher.update(Buffer.from(encryptedTextHex, 'hex')),
        decipher.final(), // 验证标签失败会在此抛出异常
      ]);
      return decrypted.toString('utf8');
    } catch (error) {
      console.error('解密失败', error);
      return '';
    }
  },
};
